package com.packtpub.learningcypher.chapter4;

import java.io.File;
import java.util.LinkedList;
import java.util.List;
import org.neo4j.graphdb.*;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;

/**
 * Database setup and data creation.
 * Section: Performance Issues
 * 
 * @author Onofrio Panzarino
 */
public class DatabaseSetup {

    private static final String DB_PATH = "database/perf";

    /**
     * Creates an empty database
     *
     * @return an empty database
     */
    public GraphDatabaseService create() {
        GraphDatabaseFactory graphDbFactory = new GraphDatabaseFactory();
        GraphDatabaseService db = graphDbFactory.newEmbeddedDatabase(DB_PATH);
        return db;
    }

    public void setup(GraphDatabaseService graphDb) {
        try (Transaction tx = graphDb.beginTx()) {
            final String[] groups = new String[]{"Music", "Books", "Movies", "HiTech"};
            
            final List<Node> groupNodes = new LinkedList<>();
            final Label groupLabel = DynamicLabel.label("Group");
            
            for (String group : groups) {
                final Node node = graphDb.createNode();
                node.setProperty("name", group);
                node.addLabel(groupLabel);

                groupNodes.add(node);
            }

            final Label userLabel = DynamicLabel.label("User");
            final Label inactive = DynamicLabel.label("Inactive");
            final RelationshipType joined = DynamicRelationshipType.withName("JOINED");
            
            for (int i = 0; i < 1000; i++) {
                final Node node = graphDb.createNode();
                node.addLabel(userLabel);

                if (i % 100 == 0) {
                    node.addLabel(inactive);
                }
                
                final String email = "user" + i + "@learningcypher.com";
                node.setProperty("email", email);
                node.setProperty("userId", i);
                
                int group = i % groups.length;
                node.createRelationshipTo(groupNodes.get(group), joined);
            }

            tx.success();
        }
    }

    /**
     * Deletes the existing database files
     *
     * @return {true} if the operation succedees
     */
    public boolean clearAll() {
        File f = new File(DB_PATH);
        return delete(f);
    }

    /**
     * Delete the file specified and all children
     *
     * @param f
     * @return {true} if the operation succedees
     */
    private boolean delete(File f) {
        if (f.isDirectory()) {
            for (File c : f.listFiles()) {
                delete(c);
            }
        }
        return f.delete();
    }

}
